﻿using System.Collections.Generic;
using System.Linq;
using HK.Core.Common.Data;
using HK.Core.Extend;
using HK.Editor.GUIEx.Protocol.Data;
using HK.Editor.GUIEx.Protocol.TreeView.Control;
using HK.Editor.GUIEx.Protocol.TreeView.Data;
using HK.Editor.GUIEx.Protocol.Window;
using HK.Editor.GUIEx.TreeView.Control;
using HK.Editor.GUIEx.TreeView.Data;
using UnityEditor;
using UnityEditor.IMGUI.Controls;
using UnityEngine;

namespace HK.Editor.GUIEx.Window
{
    
    /// <summary>
    /// 列头部
    /// </summary>
    internal class TableColumnHeader : MultiColumnHeader
    {
        /// <summary>
        /// 列模式
        /// </summary>
        public enum ColumnMode
        {
            LargeHeader,
            DefaultHeader,
            MinimumHeaderWithoutSorting
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="iState">State</param>
        public TableColumnHeader(MultiColumnHeaderState iState) : base(iState)
        {
            State = ColumnMode.DefaultHeader;
        }

        private ColumnMode _state;
        public ColumnMode State
        {
            get => _state;
            set
            {
                _state = value;
                switch (_state)
                {
                    case ColumnMode.LargeHeader:
                        canSort = true;
                        height = 37f;
                        break;
                    case ColumnMode.DefaultHeader:
                        canSort = true;
                        height = DefaultGUI.defaultHeight;
                        break;
                    case ColumnMode.MinimumHeaderWithoutSorting:
                        canSort = false;
                        height = DefaultGUI.minimumHeight;
                        break;
                }
            }
        }

        protected override void ColumnHeaderGUI (MultiColumnHeaderState.Column iColumn, Rect iRect, int iColumnIndex)
        {
            // Default column header gui
            base.ColumnHeaderGUI(iColumn, iRect, iColumnIndex);

            // Add additional info for large header
            if (ColumnMode.LargeHeader == State)
            {
                // Show example overlay stuff on some of the columns
                if (iColumnIndex > 2)
                {
                    iRect.xMax -= 3f;
                    var oldAlignment = EditorStyles.largeLabel.alignment;
                    EditorStyles.largeLabel.alignment = TextAnchor.UpperRight;
                    GUI.Label(iRect, 36 + iColumnIndex + "%", EditorStyles.largeLabel);
                    EditorStyles.largeLabel.alignment = oldAlignment;
                }
            }
        }
    }
    
    /// <summary>
    /// 窗体
    /// <para>* 拥有多列列表的窗体</para>
    /// </summary>
    /// <typeparam name="TWin">窗体类型</typeparam>
    /// <typeparam name="TConf">窗体配置类型</typeparam>
    /// <typeparam name="TTree">窗体树形数据类型</typeparam>
    /// <typeparam name="TBranch">分支类型</typeparam>
    public abstract class MultiColsWindow<TWin, TConf, TTree, TBranch> : WindowBase<TWin, TConf, TTree>, IMultiColsWindow<TWin, TConf, TTree>
        where TWin : WindowBase, IWindow<TConf, TTree>
        where TConf : JsonData, IWindowConf
        where TTree : JsonData, IWindowData, new()
        where TBranch : JsonData, ITreeBranch, new()
    {

#region TableTree
        
        [SerializeField]
        private TreeViewState tableState = null;
        /// <summary>
        /// 表状态
        /// </summary>
        public TreeViewState TableState
        {
            get => tableState;
            private set => tableState = value;
        }

        [SerializeField]
        private MultiColumnHeaderState tableHeader = null;
        /// <summary>
        /// 表头
        /// </summary>
        public MultiColumnHeaderState TableHeader 
        {
            get => tableHeader;
            private set => tableHeader = value;
        }

        /// <summary>
        /// 根节点
        /// </summary>
        public ITreeBranch Root { get; private set; } = null;

        /// <summary>
        /// 表体
        /// </summary>
        protected IMultiColTableTree<TBranch> TableTree { get; private set; } = null;

        /// <summary>
        /// 生成表头
        /// </summary>
        /// <param name="iWidth">TableView宽度</param>
        /// <returns>表头</returns>
        protected abstract MultiColumnHeaderState GenerateTableHeader(float iWidth);
        
        /// <summary>
        /// 生成根节点
        /// </summary>
        /// <returns>根节点</returns>
        protected virtual TBranch GenerateRoot()
        {
            var root = new TBranch
            {
                Id = 0,
                Depth = -1
            };
            return root;
        }
        
        /// <summary>
        /// 树枝列表
        /// </summary>
        protected abstract IList<TBranch> Branches { get; }

        /// <summary>
        /// 生成树枝列表
        /// </summary>
        /// <param name="iRoot">根节点</param>
        /// <returns>树枝列表</returns>
        protected virtual IList<TBranch> GenerateTreeBranches(TBranch iRoot)
        {
            if (null == iRoot) return null;
            var branches = new List<TBranch> { iRoot };
            if (!iRoot.Valid) return branches;
            
            if (null != Branches && 0 < Branches.Count)
            {
                branches.AddRange(Branches);
            }
			
            // 重新排序
            branches = branches
                .OrderByDescending(iO => iO.IsRoot)
                .ThenBy(iO => iO.Name)
                .ToList();
            return branches;
        }

        /// <summary>
        /// 生成数据容器
        /// </summary>
        /// <returns>数据容器</returns>
        protected virtual ITableTreeDataContainer<TBranch> GenerateTreeDataContainer()
        {
            // 生成根节点
            var rootBranch = GenerateRoot();
            Root = rootBranch;

            // 生成数据容器
            var dataContainer = GenerateTreeDataContainer(GenerateTreeBranches(rootBranch));
            if (null == dataContainer)
            {
                this.Error("GenerateTreeDataContainer() Failed!");
                return null;
            }
            return dataContainer;
        }
        
        /// <summary>
        /// 生成数据容器
        /// </summary>
        /// <param name="iBranches">树枝列表</param>
        /// <returns>数据容器</returns>
        private ITableTreeDataContainer<TBranch> GenerateTreeDataContainer(IList<TBranch> iBranches)
        {
            return new TableTreeDataContainer<TBranch>(iBranches);
        }
        
        /// <summary>
        /// 列数
        /// </summary>
        protected abstract int ColumnsCount { get; }

        /// <summary>
        /// 折叠箭头所在列索引
        /// </summary>
        protected virtual int FoldoutColIndex => -1;
        
        /// <summary>
        /// 生成表树
        /// </summary>
        /// <param name="iState">状态</param>
        /// <param name="iHeader">表头</param>
        /// <param name="iContainer">数据容器</param>
        /// <param name="iFoldoutColIndex">折叠箭头所在列索引</param>
        /// <returns>表树</returns>
        private IMultiColTableTree<TBranch> GenerateTableTree(TreeViewState iState, MultiColumnHeader iHeader, 
            ITableTreeDataContainer<TBranch> iContainer, int iFoldoutColIndex)
        {
            return new MultiColTableTree<TBranch>(iState, iHeader, iContainer, 
                ColumnsCount, SortByColumns, DrawTableTreeColumn, iFoldoutColIndex);
        }
        
        /// <summary>
        /// 根据列排序
        /// </summary>
        /// <param name="iHeaderColumns">头部列</param>
        /// <param name="iRoot">根节点</param>
        protected abstract void SortByColumns(MultiColumnHeader iHeaderColumns, TreeViewItem iRoot);

        /// <summary>
        /// 初始化排序
        /// </summary>
        /// <param name="iHeaderColumns">头部列</param>
        /// <param name="iRows">行列表</param>
        /// <param name="iColumnIndexes">列索引列表</param>
        /// <returns>可排序的列表</returns>
        protected abstract IOrderedEnumerable<TreeViewRow<TBranch>> InitialOrder(
            MultiColumnHeader iHeaderColumns, IEnumerable<TreeViewRow<TBranch>> iRows, 
            int[] iColumnIndexes);
        
#endregion
        
#region Control

        /// <summary>
        /// 检索Bar
        /// </summary>
        protected SearchField SearchBar { get; private set; } = null;
        
#endregion

#region Init

        /// <summary>
        /// 初始化属性结构视图
        /// </summary>
        protected override void InitTreeView()
        {
            if (null == tableState)
            {
                tableState = new TreeViewState();
            }
            
            var firstInit = null == tableHeader;
            var tableHeaderTmp = GenerateTableHeader(TreeWidth);
            if (MultiColumnHeaderState.CanOverwriteSerializedFields(TableHeader, tableHeaderTmp))
            {
                MultiColumnHeaderState.OverwriteSerializedFields(TableHeader, tableHeaderTmp);
            }
            TableHeader = tableHeaderTmp;
            
            var columnHeader = new TableColumnHeader(tableHeaderTmp);
            if (firstInit)
            {
                columnHeader.ResizeToFit ();
            }
            
            // 生成数据容器
            var dataContainer = GenerateTreeDataContainer();
            if (null == dataContainer)
            {
                this.Error("InitTreeView():GenerateTreeDataContainer() Failed!");
                return;
            }

            // 表树
            TableTree = GenerateTableTree(tableState, columnHeader, dataContainer, FoldoutColIndex);

            // 可检索
            if (Searchable)
            {
                SearchBar = new SearchField();
                
                // 绑定事件
                if (TableTree is UnityEditor.IMGUI.Controls.TreeView treeView)
                {
                    SearchBar.downOrUpArrowKeyPressed += treeView.SetFocusAndEnsureSelectedItem;
                }
            }

        }

#endregion

#region Position&Size

        /// <summary>
        /// 树形视图显示区域
        /// </summary>
        public virtual Rect TreeRect => new Rect(20, 30, Width - 40, Height - 60);

        /// <summary>
        /// 树形视图位置
        /// </summary>
        public Vector2 TreePos => TreeRect.position;

        /// <summary>
        /// 树形视图宽度
        /// </summary>
        public float TreeWidth => TreeRect.width;

        /// <summary>
        /// 树形视图高度
        /// </summary>
        public float TreeHeight => TreeRect.height;

#endregion

#region Draw

        /// <summary>
        /// 绘制TableTree的列
        /// </summary>
        /// <param name="iRect">绘制矩形范围</param>
        /// <param name="iDefine">宏定义</param>
        /// <param name="iRowIndex">行索引</param>
        /// <param name="iColumnIndex">列索引</param>
        protected abstract void DrawTableTreeColumn(Rect iRect, TBranch iDefine, int iRowIndex, int iColumnIndex);

#endregion
        
        /// <summary>
        /// 刷新
        /// </summary>
        public override void Refresh()
        {
            // 生成数据容器
            var dataContainer = GenerateTreeDataContainer();
            if (null == dataContainer)
            {
                this.Error("Refresh():GenerateTreeDataContainer() Failed!");
                return;
            }
            
            // 刷新
            TableTree?.Refresh(dataContainer);
        }

        public override void Apply()
        {
            throw new System.NotImplementedException();
        }
    }
}
